#include "startup.h"
#include "ui_startup.h"
#include "constants.h"
#include "log4z.h"
#include "controller.h"
#include "infoui.h"
#include <QTimer>
#include <QDateTime>
#include <QFile>
#include <QMessageBox>
#include <QTextStream>

extern int MAJORVER;
extern int MINORVER;
extern int REVIVER;

StartUp::StartUp(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::StartUp),
    iUsedForSystem(0)
{
    ui->setupUi(this);
    setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint );
    //load logo and background
    QPixmap lg(logoStr);
    ui->logo->setPixmap(lg);
    QPixmap bg(backgroundStr);
    QPalette background;
    background.setBrush(QPalette::Background, QBrush(bg));
    setPalette(background);
    //set font color
    QPalette pe;
    pe.setColor(QPalette::WindowText,Qt::white);
    ui->cTime->setPalette(pe);
    ui->lVer->setPalette(pe);
    ui->title->setPalette(pe);
    ui->info->setPalette(pe);
    //hide button
    ui->btnOne->setVisible(false);
    ui->btnTwo->setVisible(false);
    QString qVer = QString("%1 %2.%3.%4").arg(tr("Version: ")).arg(MAJORVER).arg(MINORVER).arg(REVIVER);
    ui->lVer->setText(qVer);
    //button style
    ui->btnOne->setStyleSheet(blueBtn);
    ui->btnTwo->setStyleSheet(greenBtn);
    QPalette btnPe;
    btnPe.setColor(QPalette::ButtonText,Qt::white);
    ui->btnOne->setPalette(btnPe);
    ui->btnTwo->setPalette(btnPe);

    upThread = new upgradeHelper(this);
    connect(upThread, SIGNAL(needUpgrade(int)), SLOT(onUpgrade(int)));
    upThread->start();

    QTimer *upTime = new QTimer(this);
    connect(upTime,SIGNAL(timeout()),this,SLOT(updateTime()));
    updateTime();
    upTime->start(1000);
    //set error
    Controller ct;
    ct.NormalIo();
}

StartUp::~StartUp()
{
    delete ui;
    delete dcThread;
    delete upThread;
}

void StartUp::onPogressChange(int iv)
{
    Controller gEttaCtrl;
    int iTot = 0;
    int iSt = 0;
    LOGFMTD("Progress change value %d", iv);
    if (iv <= 40 && iv >= 0)
    {
        ui->info->setText(tr("Testing, please wait..."));
    }
    else if (iv <= 80 && iv > 40)
    {
        ui->info->setText(tr("Testing, please wait...\n   Testing control system..."));
    }
    else if (iv > 80)
    {
        ui->info->setText(tr("Testing, please wait...\n   Testing control system...\n Testing peristaltic pump..."));
    }
    if (iv <= 100 && iv >= 0)
    {
        ui->progressBar->setValue(iv);
    }

    //Everything is ok, we need to get to main
    if (iv == 100)
    {
        this->hide();
        emit sendShow();
    }
    else if (iv > 8000)
    {
        switch (iv) {
        case 8001:
            this->hide();
            emit sendErr(tr("Error code: 0x8001\n----Communication error"));
            break;
        case 8002:
            this->hide();
            emit sendErr(tr("Error code: 0x8002\n----Peristaltic pump error"));
            break;
        case 8003:
            this->hide();
            emit sendErr(tr("Error code: 0x8003\n----Rotating motor error"));
            break;
        case 8004:
            this->hide();
            emit sendErr(tr("Error code: 0x8004\n----Shaker error"));
            break;
        case 8005:
            this->hide();
            emit sendErr(tr("Error code: 0x8005\n----Door error"));
            break;
        case 8006:
            this->hide();
            emit sendErr(tr("Error code: 0x8006\n----High voltage power supply error"));
            break;
        case 8007:
            this->hide();
            emit sendErr(tr("Error code: 0x8007\n----IGBT error"));
            break;
        case 8008:
            //
            emit powerOff();
            QThread::msleep(500);
            LOGD("Power off stop light, rudong, motor, yaodong, door...");
            gEttaCtrl.StopLight();
            gEttaCtrl.StopRuDong();
            gEttaCtrl.StopMotor();
            gEttaCtrl.CloseDoor();
            //Default the dianjiguan
            iSt = gEttaCtrl.StartIo();
            if (iSt == 1)
            {
                //guiwei
                gEttaCtrl.SpeedMotor(1);
                gEttaCtrl.StartMotor();
                while (iSt == 1 && iTot++ <= 20)
                {
                    QThread::msleep(200);
                    iSt = gEttaCtrl.StartIo();
                }
                gEttaCtrl.StopMotor();
            }
            gEttaCtrl.CloseYao();
            //
            destroy();
            system("echo out > /sys/class/gpio/gpio2/direction");

            break;
        default:
            break;
        }
    }
}

void StartUp::onUpgrade(int iv)
{
    if (iv == 0)
    {
        //not do
        ui->btnOne->setVisible(false);
        ui->btnTwo->setVisible(false);
        ui->progressBar->setVisible(true);
        on_btnOne_clicked();
    } else if (iv == 1)
    {
        //do
        ui->info->setText(tr("Delete U disk plugged in, You can do:"));
        ui->btnOne->setVisible(true);
        ui->btnTwo->setVisible(true);
        ui->progressBar->setVisible(false);
    }
}

void StartUp::updateTime()
{
    QDateTime curTime = QDateTime::currentDateTime();
    QString lblTm = curTime.date().toString("yyyy/MM/dd") + "\n " + curTime.time().toString("hh:mm:ss");
    this->ui->cTime->setText(lblTm);
}

void StartUp::upgradeApp()
{
    system("cp /mnt/ver.txt /home/root/ver.txt");
    ui->progressBar->setValue(10);
    QThread::msleep(100);
    ui->progressBar->setValue(20);
    QThread::msleep(300);
    system("cp /mnt/fiapp /home/root/matrix_browser");
    ui->progressBar->setValue(30);
    QThread::msleep(500);
    ui->progressBar->setValue(40);
    QThread::msleep(500);
    system("cp /home/root/matrix_browser /usr/bin/matrix_browser");
    ui->progressBar->setValue(50);
    QThread::msleep(100);
    ui->progressBar->setValue(60);
    QThread::msleep(300);
    ui->progressBar->setValue(70);
    QThread::msleep(500);
    system("cp /mnt/params.txt /home/root/params.txt");
    ui->progressBar->setValue(80);
    QThread::msleep(100);
    ui->progressBar->setValue(90);
    QThread::msleep(300);
    ui->progressBar->setValue(100);
    ui->info->setText(tr("System upgraded, please reboot..."));
    iUsedForSystem = 100;
    ui->progressBar->setVisible(false);
    ui->btnTwo->setVisible(true);
    ui->btnTwo->setText(tr("Reboot"));
}

void StartUp::on_btnTwo_clicked()
{
    //normal upgrade
    //version high directlydo
    if (iUsedForSystem == 0)
    {
        QFile file("/mnt/ver.txt");
        if(!file.open(QIODevice::ReadOnly|QIODevice::Text))
        {
            //error
            LOGFMTD("Can't find version file");
        }
        //... (open the file for reading, etc.)
        QTextStream textStream(&file);
        QString qVersion = textStream.readAll();

        LOGFMTD("Upgrade version text %s", qVersion.toStdString().c_str());
        QStringList verDetail = qVersion.split(".");
        if (verDetail.size() == 3)
        {
            //ok
            int iMajor = verDetail.at(0).toInt();
            int iMinor = verDetail.at(1).toInt();
            int iRev = verDetail.at(2).toInt();
            LOGFMTD("latest ver %d %d %d", iMajor, iMinor, iRev);
            if (iMajor > MAJORVER ||
                (iMajor == MAJORVER && iMinor > MINORVER) ||
                (iMajor == MAJORVER && iMinor == MINORVER && iRev > REVIVER) ) {
                ui->info->setText(tr("Upgrading, please wait..."));
                ui->btnOne->setVisible(false);
                ui->btnTwo->setVisible(false);
                ui->progressBar->setVisible(true);
                upgradeApp();
            } else {
                ui->info->setText(tr("Version is lower than system, You can:"));
                ui->btnOne->setVisible(true);
                ui->btnOne->setText(tr("Exit"));
                ui->btnTwo->setVisible(true);
                ui->btnTwo->setText(tr("Continue"));
                ui->progressBar->setVisible(false);
                iUsedForSystem = 10;
            }
        }

    } else if (iUsedForSystem == 10) {
        ui->info->setText(tr("Upgrading, please wait..."));
        ui->btnOne->setVisible(false);
        ui->btnTwo->setVisible(false);
        ui->progressBar->setVisible(true);
        upgradeApp();
    } else if (iUsedForSystem == 100) {
        //reboot
        QThread::msleep(800);
        this->close();
#if defined(__linux__) || defined(__FreeBSD__)
        system("echo 0 > /sys/class/gpio/gpio113/value");
        system("reboot");
#endif
    }
}

void StartUp::on_btnOne_clicked()
{
    ui->btnOne->setVisible(false);
    ui->btnTwo->setVisible(false);
    ui->progressBar->setVisible(true);
    //start up
    dcThread = new DevChecker(this);
    connect(dcThread, SIGNAL(progressChange(int)), SLOT(onPogressChange(int)));
    dcThread->start();
}
